package com.sz.aspect;

import com.sz.bean.Constants;
import com.sz.controller.frame.BaseController;
import com.sz.exception.WebFindException;
import com.sz.pojo.frame.User;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * aop的初步实现 基于注解的AOP日志
 * 
 * 种类 摘抄 {@docRoot} 我这里写的比较全，前置通知，环绕通知，后置通知，异常通知，后置饭后通知，都写上了，
 *           {@docRoot} 在我们实际编写中不写全也没事，我习惯上把记录日志的逻辑写在后置通知里面，我看网上也有些在前置通知里面的，
 *           但我感觉写在后置通知里比较好。
 */
@Aspect
@Component
public class SystemLogAspect {

    // 注入Service用于把日志保存数据库
    // @Autowired //这里我用resource注解，一般用的是@Autowired，他们的区别如有时间我会在后面的博客中来写
    // private SystemLogService systemLogService;

    @Autowired
    private HttpServletRequest httpServletRequest;
    @Autowired
    private HttpSession httpSession;

    // private static final Logger logger =
    // LoggerFactory.getLogger(SystemLogAspect. class);

    // Controller层切点
    @Pointcut("within ( @org.springframework.stereotype.Controller * )")
    public void controllerAspect() {
    }

    // service层切点
//    @Pointcut("execution (* com.sz.service..*.*(..))")
//    public void serviceAspect() {
//    }

    /**
     * 前置通知 用于拦截Controller层记录用户的操作
     * 
     * @param joinPoint
     *            切点
     */
    @Order(4)
    @Around("controllerAspect()")
    public Object doBefore(ProceedingJoinPoint joinPoint)  throws Throwable {
        Object obj = null;
        Model m = null;
        Object[] args = joinPoint.getArgs();
        for (Object o : args) {
            if (o instanceof Model) {
                m = (Model) o;
            }
        }
        try {
            String methodname = joinPoint.getSignature().getName();
            if (!"exit".equals(methodname)
                    && !"checkCode".equals(methodname)
                    && !"inputVerification".equals(methodname)
                    && !"login".equals(methodname)
                    && !"weblist".equals(methodname)
                    ){
                User user = (User) httpSession.getAttribute(Constants.SESSION_USER);
                if (user == null ){
                    return "../../admin/login";
                }
            }
            obj = joinPoint.proceed();
        } catch (RuntimeException e) {
            if (m != null) {
                m.addAttribute("msg", e.getMessage());
            }
            if (e instanceof WebFindException) {
                return BaseController.WEB_404;
            }
                return "../../admin/message";
        }
        return obj;
    }

}
